// JavaScript Document

var pageManager = {

    /*Public: User-agent booleans*/
    isIE: false,
    isOpera: false,
    isSafari: false,
    isKonquerer: false,
    isGecko: false,
    isSupported: false,

    /* Object variables */
    defaultLoadMethod: 'POST',
    callBackMethod: null,
    targetDiv: null,
    loaderImageSrc: null,
    ajaxObject: null,
    http_result: null,
    ajax_load_done: null,
    supports_back_button: false,
    use_iframe: false,
    slideTimerId : null, // timer for the show/hide function
    slideEndFunc: null, // function called at the end of the show/hide
	
    okButtonAction: null, /** OK Button Action */
    cancelButtonAction: null, 	/** Cancel Button Action */

    // collections of returned elements from the DOM
    els: null,
	
    // global ajax configuration
    ajax_config: {},

    isFunction: function( obj ) {
        return Object.prototype.toString.call(obj) === "[object Function]";
    },

    /**
     * A simplified selector function, similar to that of JQuery.
     * Returns a single object based on the selector or id, or null if nothing is found
	 *
	 * @param selector
     */
    $: function(selector) {
		
        // if the supplied selector is actually an object or HTMLElement
        // return that instead trying to search through the DOM. This is
        // useful for other functions that make use of the selector API
        // but may be passed an object reference instead of a selector string
        if( typeof(selector) == "object" ) {
            return selector;
        }
		
        // check the existence of the api
        if( document.querySelector ) {
            var el = null;
			
            try {
                el = document.querySelector( selector );
            } catch(e) {}
			
            // the select search did not return a result, then fall back
            // and try to return the element based on the id
            if( el == null ) {
                try {
                    el = document.getElementById(selector);
                } catch(e) {}
            }
			
            // return whatever we have so far
            return el;
			
        // query selector is not supported
        // and the selector starts with a hash
        } else if( selector.substring(0,1) == "#" ) {
            var fp = selector.split(" ")[0]; // incase of selector chain
            return document.getElementById( fp.substring(1, fp.length ) );
			
        } else {
            // return the results of trying to use the id if available
            return document.getElementById(selector);
			
        }
    },

    el: function(selector) {
        // try to return all the elements that match this selector
        this.els = pageManager.all(selector);

        // if the previous call does not return any elements then return
        // an array containing the first element that matches the selector
        if( this.els == null ) {
            this.els = [ pageManager.$(selector) ];
        }

        return this;
    },

    /**
     * Returns all elements that match the specified selector.
     * Returns null if the browser does not support the document.querySelectorAll function
	 *
	 * @param selector
	 * @param func
     */
    all: function(selector, func) {
        if( document.querySelectorAll ) {
            var els = null;

            try {
                els = document.querySelectorAll(selector);
            } catch(e) {
                return null;
            }

			
            // create a closure to prevent the index variable from changing
            // when the function is called
            var fn = function(el, i) {
                func(el, i);
            }
			
            // if the method was called with a specified function,
            // call the func by passing each element in the list to it
            if( func != null ) {
                for(var i = 0; i < els.length; i++) {
                    fn(els[i], i);
                }
            }
			
            // return all elements found
            return els;
        }
		
        return null;
    },
    
    /**
     * Creates an element of the Tag and uses it for the rest of the pageManager
     * manipulations. This function will replace any previously selected elements
     * from the DOM.
     * 
     * @param tagName the name of tag to create
     **/
    create: function(tagName) {
        
        if( this.isString(tagName) ) {
            var elem = document.createElement(tagName);
            
            // replace all elements currently selected elements
            this.els = [elem];
            
            return this;
        }
        
        return null;
    },
	
	/**
	 * Returns the actual HTMLElement from the selected list of items at the specified
	 * index
	 *
	 * @param index the index in the list to return
	 */
	node: function(index) {
		if( this.els == null || this.els.length == 0 ) {
            return this;
        }
		
		if( index == null ) index = 0;
		
		if( index >= 0 ) {
			return this.els[index];	
		}
        
        return this;
	},
    
    /**
     * Returns the total number of selected elements from the DOM
     * 
     * @return total number of selected elements
     */
    count: function() {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }
        
        return this.els.length;
    },
    
    append: function(elem) {
        
        
    },
	
    /**
     * adds an event to the element specified by the CSS Selector
	 *
	 * @param selector
	 * @param type
	 * @param func
     */
    addEvent: function(selector, type, func) {
        
        var doAdd = function(elem) {
            // if this a link, then prevent the default behaviour
            if( elem.tagName && elem.tagName == "A") {
                elem.onclick = function() {
                    return false;
                };
            }
				
            if( elem.addEventListener ) {
                elem.addEventListener(type, func, false);
            } else if( elem.attachEvent ) {
                elem.attachEvent("on" + type, func);
            }

        };
		
        if( typeof(selector) == 'string' ) {
            if( pageManager.all(selector) ) {
                pageManager.all(selector, doAdd);
            }
			
            if( pageManager.$(selector) ) {
                doAdd( pageManager.$(selector) );
            }
			
        } else if( typeof(selector) == 'object' ) {
            //elems = [selector];
            doAdd(selector);
        }
		
        return this;
    },

    _access: function(area, property, value) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        // if we are trying to retrieve a property, then use only the 
        // first element
        var el = this.els[0];
		
        if( property && (value == null || !value) ) {
            if( el && el.nodeType === 1 ) {
                switch(area) {
                    case 'css':
                        return el.style[property];
                    case 'attr':
                        return el.getAttribute(property);
                    case 'val':
                        return el.value;
                    case 'html':
                        return el.innerHTML;
					case 'text':
                        return el.textContent;
                    default:
                        return this;
                }
            }

        } else if( !property && !value ) {
            return this;
        }

        // if setting a property, then loop through all available elements
        // update the properties of each
        for(var i = 0; i < this.els.length; i++ ) {
            el = this.els[i];
            if( el && el.nodeType === 1 ) {
                switch(area) {
                    case 'css':
                        el.style[property] = value;
                        break;
                    case 'attr':
                        // convert value to string incase value is object or numeric
                        el.setAttribute(property,'' + value);
                        break;
                    case 'val':
                        el.value = value;
                        break;
                    case 'html':
                        el.innerHTML = value;
                        break;
					case 'text':
						el.textContent = value;
						break;
                }
            }
        }

        return this;
    },

    /**
     * Sets or returns a css property
     * 
     * @param property the css property to return or set
     * @param value the value of the CSS property to set
     */
    css: function( property, value ) {
        return this._access('css', property, value);
    },

    /**
     * Sets or return an attribute of the selected elements
     * 
     * @param attribute the attribute to return or set
     * @param value the value of the attribute to set
     * @return the value of the attribute of the value parameter is not set
     */
    attr: function( attribute, value ) {
        return this._access('attr', attribute, value);
    },
	
	removeAttr: function(attribute) {
		if( this.els == null || this.els.length == 0 ) {
            return this;
        }
		
		this._access("attr", attribute, "");
		
		for(var i = 0; i < this.els.length; i++) {
			if( this.els[i].nodeType === 1 ) {
				this.els[i].removeAttribute( attribute );	
			}	
		}
		
		return this;
	},

    val: function( value ) {
        return this._access('val', 1, value);
    },

    html: function( value ) {
        return this._access('html', 1, value);
    },
	
	text: function( value ) {
		return this._access('text', 1, value);
	},

    addClass: function(className) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        for(var i = 0; i < this.els.length; i++) {
			if( this.els[i] != null ) {
				var cn = this.els[i].className;
	
				if( cn.indexOf(className) == -1 ) {
					cn += " " + className;
					this.els[i].className = cn;
				}
			}
        }

        return this;
    },

    removeClass: function(className) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        for(var i = 0; i < this.els.length; i++) {
            var cn = this.els[i].className;
            
            if( cn.indexOf(className) > -1 ) {
                cn = cn.replace(" " + className, " ");
                this.els[i].className = cn;
            }
        }

        return this;
    },

    /**
     * adds an event to the element specified by the CSS Selector
	 *
	 * @param type
	 * @param func
     */
    bind: function(type, func) {

        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        if( !type && !func ) {
            return this;
        }

        var doAdd = function(elem) {

            if( elem == null ) {
                return;
            }
            
            // if this a link, then prevent the default behaviour
            if( elem.tagName && elem.tagName == "A") {
                elem.onclick = function() {
                    return false;
                };
            }

            if( elem.addEventListener ) {
                elem.addEventListener(type, func, false);
            } else if( elem.attachEvent ) {
                elem.attachEvent("on" + type, func);
            }

        };

        for(var i = 0; i < this.els.length; i++ ) {
            doAdd(this.els[i]);
        }

        return this;
    },

    unbind: function(type, func) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        if( !type && !func ) {
            return this;
        }

        var doRemove = function(elem) {

            if( elem == null ) {
                return;
            }

            // if this a link, then prevent the default behaviour
            if( elem.tagName && elem.tagName == "A") {
                elem.onclick = null;
            }

            if( elem.addEventListener ) {
                elem.removeEventListener(type, func, false);
            } else if( elem.attachEvent ) {
                elem.detachEvent("on" + type, func);
            }

        };

        for(var i = 0; i < this.els.length; i++ ) {
            doRemove(this.els[i]);
        }

        return this;
    },
	
	fire: function(type) {
		if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        if( !type ) {
            return this;
        }
		
		for(var i = 0; i < this.els.length; i++ ) {
			var handle = this.els[i][type];
			if( handle && this.isFunction(handle) ) {
            	handle.apply( this.els[i] );
			}
        }
	},

    serialize: function() {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        if( this.els[0].toString() === "[object HTMLFormElement]" || 
            this.els[0].tagName.toLowerCase() == "form" ) { // second check for IE8 or lower browsers
					
            return pageManager.buildQuery( this.els[0] );
        }

        return null;
    },

    load: function(page, query, callback) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }
        
        this.post(page, query, this.els[0], callback);

        return this;
    },

    toggleSlide: function(func) {
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        var e = this.els[0];

        if( e.style.display == "none" ) {
            this.show( func );
        } else {
            this.hide( func );
        }

        return this;
    },
    
    isNotEmpty: function (strValue) {
        return (strValue != null && strValue != "" && strValue.length != 0);
    },

    isString: function(strValue) {
        return (typeof strValue == 'string' && strValue != '' && isNaN(strValue));
    },

    isNumber: function(strValue) {
        return (!isNaN(strValue) && strValue != '');
    },

    isEmail: function (strValue) {
        var objRE = /^[\w-\.\']{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,}$/;

        return (strValue != '' && objRE.test(strValue));
    },
    
    validate: function(map, callback) {
        
        if( this.els == null || this.els.length == 0 ) {
            return this;
        }

        if( this.els[0].toString() !== "[object HTMLFormElement]" || 
            this.els[0].tagName.toLowerCase() != "form" ) { // second check for IE8 or lower browsers
					
            return this;
        }
    
        var fieldNameMap = null;
        
        if( map != null ) {
            fieldNameMap = map;
        }
	
        var arClass, bValid;
        var objField = this.els[0].getElementsByTagName('*');
        var errorCount = 0;
        var errorFields = new Array();
        var errorFieldNames = new Array();
  
        for (var iFieldCounter=0; iFieldCounter<objField.length; iFieldCounter++)
        {
            // Allow for multiple values being assigned to the class attribute
            arClass = objField[iFieldCounter].className.split(' ');
            for (var iClassCounter=0; iClassCounter<arClass.length; iClassCounter++)
            {
                switch (arClass[iClassCounter])
                {
                    case 'required':
                        bValid = this.isNotEmpty(objField[iFieldCounter].value);
                        break;
                    case 'string':
                        bValid = this.isString(objField[iFieldCounter].value.replace(/^\s*|\s*$/g, ''));
                        break;
                    case 'number' :
                        bValid = this.isNumber(objField[iFieldCounter].value);
                        break;
                    case 'email' :
                        bValid = this.isEmail(objField[iFieldCounter].value);
                        break;
                    default:
                        bValid = true;
                }

                if (bValid == false) {
		
                    // if a field name map exists then user expects to provide extra functionality
                    // hence, simply list errors and continue
                    if( fieldNameMap != null ) {
                        errorFields[errorCount] = fieldNameMap[objField[iFieldCounter].name];
                        errorFieldNames[errorCount++] = objField[iFieldCounter].name;
                    //objField[iFieldCounter].style.border = "solid red 1px";
			
                    // If this field is invalid, leave the testing early,
                    // and alert the visitor to this error
                    } else {
                        alert('Please review the value you provided for ' + objField[iFieldCounter].name);
			
                        objField[iFieldCounter].select();
                        objField[iFieldCounter].focus();
                        return false;
                    }
       
                } else {
                }
            }
        }
 
        // if errors have been listed
        if( errorFields.length > 0 ) {
            // new addition: we will now display form errors on the field as well
            // in order to make the errors more visible
            var errors = "<br>";
            for( var i = 0; i < errorFields.length; i++ ) {
                errors = errors + "&nbsp;  - " + errorFields[i] + "<br>";

                var fieldEl = document.getElementById( errorFieldNames[i] );

                fieldEl.style.border = "solid red 1px";
                fieldEl.onblur = function() {
                    if( this.value != null && this.value != "" ) {
                        this.style.border = "solid #bbb 1px";
                    }
                };
            }
	
            // check if user specified a way to handle the errors
            if( callback != null  ) {
                callback();
		
            // simply display the errors via an alert prompt
            } else {
                errors = "Please Check The Following Fields For Errors\n"
                for( var i = 0; i < errorFields.length; i++ ) {
                    errors = errors + "  - " + errorFields[i] + "\n";
                }
		
                alert( errors );
            }
	
            // ensure to indicate that there are errors in the current form
            return false;
        }
  
        return true;
    },


    /**
     * Sets the default load method to use if none is specified
     **/
    setDefaultLoadMethod: function(method) {
        pageManager.defaultLoadMethod = method;
    },

    /* Public: Retrieves the current default load method */
    getDefaultLoadMethod: function() {
        return pageManager.defaultLoadMethod;
    },

    /**
     * Display the specified Element's content as the load progess information
     * for the target load activity. This method is called from within the loadContent
     * method
     */
    showContentLoadProgress: function (area,loader) {
        var areaEl = pageManager.$(area);
        var loaderEl = pageManager.$(loader);

        if( loaderEl != null && areaEl != null ) {
            areaEl.innerHTML = loaderEl.innerHTML;
        }
    },

    /***
     * Submits a Form via AJAX using the POST method
     * 
     * @param page the AJAX processing page
     * @param area the area to display the AJAX results
     * @param form_id the id of the form to submit
     * @param callback an action to call after the request completes
     */
    postForm: function(page, area, form_id, callback) {
        var query = pageManager.buildQuery( pageManager.$(form_id) );
        pageManager.post(page, query, area, callback);
    },

    /***
     * Submits a Form via AJAX using the GET method
     * 
     * @param page the AJAX processing page
     * @param area the area to display the AJAX results
     * @param form_id the id of the form to submit
     * @param callback an action to call after the request completes
     */
    getForm: function(page, area, form_id, callback) {
        var query = pageManager.buildQuery( pageManager.$(form_id) );
        pageManager.get(page, query, area, callback);
    },

    /**
     * Makes an AJAX call to the server using the POST method. This is a simplified version of the
     * loadContent method, in that it is designed to required just the barest minimum arguments for success
     * 
     * @param page the AJAX processing page
     * @param query the query data to pass along
     * @param area the area to display the AJAX results
     * @param callback an action to call after the request completes
     */
    post: function(page, query, area, callback) {
        var method = pageManager.getDefaultLoadMethod();
        pageManager.setDefaultLoadMethod("POST");
        
        if( this.isFunction(area) && callback == null ) {
            callback = area;
            area = null;
        }
        
        pageManager.ajax(page, query, area, callback);
        
        // clean up
        pageManager.setDefaultLoadMethod(method);
    },

    /**
     * Makes an AJAX call to the server using the GET method. This is a simplified version of the
     * loadContent method, in that it is designed to required just the barest minimum arguments for success
     * 
     * @param page the AJAX processing page
     * @param query the query data to pass along
     * @param area the area to display the AJAX results
     * @param callback an action to call after the request completes
     */
    get: function(page, query, area, callback) {
        if( query.substring(0,1) != '?') {
            query = '?' + query;
        }

        var method = pageManager.getDefaultLoadMethod();
        pageManager.setDefaultLoadMethod("GET");
        
        if( this.isFunction(area) && callback == null ) {
            callback = area;
            area = null;
        }
        
        pageManager.ajax(page, query, area, callback);
        
        // clean up
        pageManager.setDefaultLoadMethod(method);
    },
	
    postMultiPartForm: function(page,formEl,area,callback) {
        if( formEl == null ) {
            return;
        }
		
		if( typeof formEl == "string" ) {
			formEl = pageManager.$(formEl);	
		}
		
        pageManager.ajax_load_done = false;
        pageManager.targetDiv = area;
        pageManager.callBackMethod = callback;
        
        if( pageManager.isIE ) {
            formEl.setAttribute("action",page);
        } else {
            formEl.action = page;
        }

        formEl.method = "POST";
        formEl.target = 'pm_loader_frame';
        formEl.submit();
		
        pageManager.showContentLoadProgress(area,'pm_loader');
        pageManager.ajax_load_done = true;
    },
	
    setUseIFrame: function(use_frame) {
        pageManager.use_iframe = use_frame;

        return this;
    },
	
    ajaxConfig: function(config) {
        pageManager.ajax_config = config;

        return this;
    },

    ajax: function(page,query,area,callback) {

        // inidicate that loading has just begun
        ajax_load_done = false;

        // store the target div for later
        pageManager.targetDiv = area;
        pageManager.callBackMethod = callback;

        if( pageManager.ajax_config.onStart ) {
            pageManager.ajax_config.onStart();
        } else {
            pageManager.showContentLoadProgress(area, 'pm_loader');
        }
		

        
        // if we need to support the browser back button functionality,
        // then we will need to use IFrame AJAX based requests
        if( pageManager.supports_back_button || pageManager.use_iframe ) {

            // using IFrame based AJAX calls for back button support works well
            // in most browsers except for Safari when doing POST based requests
            // with the form submit trick, cos the browser requests permission to
            // resubmit the form when the Back button is pressed
            if( pageManager.getDefaultLoadMethod() == "GET" ) {
                document.getElementById("pm_loader_frame").src = page + query;

            } else {

                // reset the IFrame so that if relative links are used, they will be resolved
                // against the parent frame and not the last page loaded into the IFrame
                pageManager.ajax_load_done = false;
                document.getElementById("pm_loader_frame").src = "about:blank";


                // create a new form to use for posting data
                var form = document.createElement("form");
                form.enctype = "application/x-www-form-urlencoded";
                form.target = "pm_loader_frame";
                form.method = "post";
                form.name = "postForm";
                form.id = "postForm";
                form.action = page;


                // populate the form with the data to be posted as hidden field
                var queryParts = query.split("&");
                for(i = 0; i < queryParts.length; i++) {
                    var parts = queryParts[i].split("=");
                    var field = document.createElement("input");
                    field.type = "hidden";
                    field.name = parts[0];
                    field.value = parts[1];

                    form.appendChild( field );
                }
                
                //var iFrameBody = this.extractIFrameBody("pm_loader_frame");
                //iFrameBody.appendChild( form );

                // submit the form the IFrame
                form.submit();
            }

            pageManager.ajax_load_done = true;

        // else we will need to use the traditional XHTTPRequest to fulfill
        // AJAX requests
        } else {
            var method = pageManager.getDefaultLoadMethod();
            var http_request = pageManager.getAJAXObject(area, callback);

            if( !http_request ) {
                return false;
            }

            if(method == 'GET' || method == 'DELETE' ){
                http_request.open(method, page+query, true);
                http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                http_request.setRequestHeader("Content-length", query.length);
                http_request.setRequestHeader("Connection", "close");
                http_request.send(null);
            }

            if(method == 'POST' || method == 'PUT' )  {
                http_request.open(method, page, true);
                http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                http_request.setRequestHeader("Content-length", query.length);
                http_request.setRequestHeader("Connection", "close");
                http_request.send(query);
            }
        }

        return false;
    },

    getAJAXObject: function(target, callback) {

        var http_request = false;

        if(window.XMLHttpRequest) { // Mozilla, Safari,...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                // Set type accordingly to anticipated content type.
                http_request.overrideMimeType('text/xml');
            // http_request.overrideMimeType('text/html');
            }
        } else if (window.ActiveXObject) { // IE
            try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
            }
        }

        if (!http_request) {
            alert('Cannot create XMLHttpRequest object');
            return false;
        }

        http_request.onreadystatechange = function() {
            if (http_request.readyState == 4) {
                if (http_request.status == 200) {
                    var response = http_request.responseText; // cache for local use
                    pageManager.http_result = http_request.responseText; // cache for global use

                    if( target != null ) {
                        pageManager.el( target ).html( response );
                    }

                    if( callback != null ) {
                        callback(response);
                        pageManager.setLoaderMessage(null);
                    }
					
                    if( pageManager.ajax_config.onSuccess ) {
                        pageManager.ajax_config.onSuccess(response);
                    }

                    ajax_load_done = true;
					
                } else if( http_request.status != 0 ) {
					
                    if( pageManager.ajax_config.onError ) {
                        pageManager.ajax_config.onError(http_request.responseText);
						
                    } else {
                        pageManager.showMessage({
                            title: 'Request Error: ' + http_request.status,
                            content: http_request.responseText,
                            okButtonAction: function() {
                                var el = pageManager.$( pageManager.targetDiv );
								
                                if( el != null ) {
                                    el.innerHTML = "Request Failed. Please Try Again.";
                                }
                            }
                        });
                    }
				
				
                } else if( http_request.status == 0 ) {
                // don't do anything for now, only IE is throwing this error
					
                }
				
                if( pageManager.ajax_config.onComplete ) {
                    pageManager.ajax_config.onComplete();
                }
            }
        };

        return http_request;
    },

    displayResult: function() {
        if( pageManager.ajax_load_done ) {
            var frame = document.getElementById("pm_loader_frame");
            var frame_content = null;

            if( window.navigator.userAgent.indexOf("MSIE") != -1 ) {
                if( frame.contentWindow.document.body.innerHTML != "") {
                    frame_content = frame.contentWindow.document.body.innerHTML;
                }
            } else {
                if( frame.contentDocument.body.innerHTML != "" ) {
                    frame_content = frame.contentDocument.body.innerHTML;
                }
            }

            if( pageManager.callBackMethod != null ) {
                pageManager.callBackMethod( frame_content );
            }
			
            if( pageManager.ajax_config.onSuccess ) {
                pageManager.ajax_config.onSuccess(frame_content);
            }
			
            $p(pageManager.targetDiv).html(frame_content);
        }
    },

    extractIFrameBody: function(frame_id) {
        var frameObj = document.getElementById( frame_id );

        if( window.navigator.userAgent.indexOf("MSIE") != -1 ) {
            return frameObj.contentWindow.document.body;
        } else {
            return frameObj.contentDocument.body;
        }
    },

    /**
     * (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
     * Special thanks to Dan Webb's domready.js Prototype extension
     * and Simon Willison's addLoadEvent
     *
     * For more info, see:
     * http://www.thefutureoftheweb.com/blog/adddomloadevent
     */
    addLoadEvent: function(func){
        DomLoaded.load(func);
    },

    /*
     * Builds a string that holds all the values and names of the fields in the
     * specified form
     * 
     * @return a string of parameters
     */
    buildQuery: function(form) {
        if( typeof form == "string" ) {
            form = pageManager.$(form);
        }
		
        var query = "";
        for(var i = 0; i < form.elements.length; i++) {
            var key = form.elements[i].name;
            var value = pageManager.getElementValue(form.elements[i]);

            //if(key && value) {
            query += key +"="+ encodeURIComponent(value) +"&";
        //}
        }

        return query;
    },

    getElementValue: function(formElement) {
        if(formElement.length != null && formElement.length > 0) var type = formElement[0].type;
        if((typeof(type) == 'undefined') || (type == 0)) type = formElement.type;

        switch(type) {
            case 'undefined':
                return null;

            case 'radio':
                for(var x=0; x < formElement.length; x++)
                    if(formElement[x].checked == true)
                        return formElement[x].value;

            case 'select-multiple':
                var myArray = new Array();
                for(x=0; x < formElement.length; x++)
                    if(formElement[x].selected == true)
                        myArray[myArray.length] = formElement[x].value;

                return myArray;

            case 'checkbox':
                if( formElement.checked )
                    return formElement.value;
                else
                    return formElement.checked; // return false so as not to be included in the submission

            default:
                return formElement.value;
        }
    },

    /**
     * Removes all the child nodes from the specified element
     *
     * @param element the HTMLElement from whom to remove all child elements
     */
    removeAllChildrenFrom: function(element) {
        if ( element.hasChildNodes() ) {
            while ( element.childNodes.length >= 1 ) {
                element.removeChild( element.firstChild );
            }
        }

        return this;
    },
	
    /**
     * Removes an element from the DOM structure of the page being worked on
     *
     * @param selector a CSS selector for finding the element to remove
     */
    remove: function(selector) {
		
		if( this.els != null && this.els.length > 0 ) {
			for(var i = 0; i < this.els.length; i++) {
				if( this.els[i] != null && this.els[i].parentNode ) {
					this.els[i].parentNode.removeChild( this.els[i] );	
				}	
			}
		} else {
		
			var el = pageManager.$(selector);
			
			if( el != null && el.parentNode ) {
				el.parentNode.removeChild(el);
				el = null;
			}
		}

        return this;
    },
	
    /**
     * Removes all elements returned via the query using the selector
     * from the DOM structure of the page being worked on
     *
     * @param selector a CSS selector for finding the elements to remove
     */
    removeAll: function(selector) {
        pageManager.all(selector, function(el) {
            if( el != null ) {
                el.parentNode.removeChild(el);
            }
        });

        return this;
    },
	
    /**
     * Finds the first parent node in the hierachy of the supplied element which has the
     * specified class name.
     *
     * @param el the HTMLElement whose parent must be found
     * @param cn the class name of the parent element
     */
    findFirstParentWithClass: function(el, cn) {
        if( el.parentNode != null && el.parentNode.className == cn ) {
            return el.parentNode;
        } else if( el.parentNode == null ) {
            return null;
        }
		
        return pageManager.findFirstParentWithClass( el.parentNode, cn );
    },

    /**
     * Sets the source for the image to use for the busy status indicator. if the image src
     * is set to NULL, then the loader image object will be hidden instead
     */
    setLoaderImageSrc: function(src) {
        pageManager.loaderImageSrc = src;

        var li = document.getElementById("pm_loader_image");
        if( li != null ) {
            if( src != null ) {
                li.style.display = "block";
                li.src = pageManager.loaderImageSrc;
            } else {
                li.style.display = "none";
            }
        }

        return this;
    },
	
    /**
     * Sets the message to be displayed in the result area while the content
     * is being loaded
     */
    setLoaderMessage: function(message) {
        var lm = document.getElementById("pm_loader_msg");
        if( lm != null ) {
            if( message == null ) {
                lm.innerHTML = "Loading Content. Please Wait...";
            } else {
                lm.innerHTML = message;
            }
        }

        return this;
    },
	
    /**
     * Makes a currently hidden HTMLElement visible by animating the element
     * from zero height to maximum height specified by the element CSS or the
     * auto height of the element
     */
    show: function(id, func) {
        timeToSlide = 15; // in milliseconds

        var obj = null;

        // check if the old method of supplying a selector is being used and determine
        // the object to use based on that
        if( id && !this.isFunction(id) ) {
            obj = pageManager.$(id);

        // if the ID was not passed or the passed id is a function, then determine
        // the element to use for the animation based on the fact that an object was
        // preselected using the el() function
        } else if( this.isFunction(id) ) {
            func = id;
        }
		
		if( obj == null ) {
			// if preselected elements exist, then use that
            if( this.els && this.els.length > 0 ) {
                obj = this.els[0];
            } else {

                // no object could be determined, simply return
                return this;
            }	
		}

        // configure the object
        obj.style.display = 'none'; // hidden it
        obj.style.visibility = "hidden"; // make it invisible
        obj.style.display = "block"; // make the element dimensionable
        height = obj.offsetHeight; // get the current height
        obj.style.height = "0px";
        obj.style.visibility = "visible";
        pxPerLoop = height/timeToSlide;
        pageManager.slide(obj,0,height,pxPerLoop,'down');
		
        // set the function to call once the hide operation is done
        if( func != null ) {
            pageManager.slideEndFunc = function() {
                func();
                pageManager.slideEndFunc = null;
            }
        } else {
            pageManager.slideEndFunc = null;
        }

        return this;
    },
	
    /**
     * Makes a currently visible HTMLElement hidden by animating the element
     * from maximum/auto height specified by the element CSS to zero height
     */
    hide: function(id, func) {
        timeToSlide = 15; // in milliseconds
        
        var obj = null;

        // check if the old method of supplying a selector is being used and determine
        // the object to use based on that
        if( id && !this.isFunction(id) ) {
            obj = pageManager.$(id);

        // if the ID was not passed or the passed id is a function, then determine
        // the element to use for the animation based on the fact that an object was
        // preselected using the el() function
        } else if( this.isFunction(id) ) {
            func = id;
        }
		
		if( obj == null ) {
			// if preselected elements exist, then use that
            if( this.els && this.els.length > 0 ) {
                obj = this.els[0];
                
            } else {

                // no object could be determined, simply return
                return this;
            }	
		}

        height = obj.offsetHeight;
        pxPerLoop = height/timeToSlide;
        pageManager.slide(obj,height,height,pxPerLoop,'up');
		
        // set the function to call once the hide operation is done
        if( func != null ) {
            pageManager.slideEndFunc = function() {
                func();
                pageManager.slideEndFunc = null;
            }
        } else {
            pageManager.slideEndFunc = null;
        }

        return this;
    },
	
    /**
     * Animates the HTMLElement specified by to max height or zero height
     * depending on parameters passed
     */
    slide: function(obj,offset,full,px,direction){
        if(direction == 'down'){
            if(offset < full){
                obj.style.height = offset+"px";
                offset=offset+px;
                setTimeout((function(){
                    pageManager.slide(obj,offset,full,px,'down');
                }),1);
            } else {
				
                obj.style.height = "auto"; //Can be usefull in updated divs otherwise
                //obj.style.height = full+"px"
				
                // call the callback function if one is defined
                if( pageManager.slideEndFunc != null ) {
                    pageManager.slideEndFunc();
                }
            }
        }else if(direction == 'up'){
            if(offset > 5){
                obj.style.height = offset+"px";
                offset=offset-px;
                setTimeout((function(){
                    pageManager.slide(obj,offset,full,px,'up');
                }),1);
            } else {
                obj.style.display = "none";
                obj.style.height = height+"px";
				
                // call the callback function if one is defined
                if( pageManager.slideEndFunc != null ) {
                    pageManager.slideEndFunc();
                }
            }
        }
    },
	
    /**
     * Makes the HTMLElement with the specified ID visible by slowly animating the
     * opacity property from 0 to 100 or the endOpacity value if specified
     */
    fadeIn: function(id, func, endOpacity) {
        var speed = 300;
        var end = endOpacity != null ? endOpacity : 100;
        opacity(id, 0, end, speed);
		
        if( func != null && typeof func == 'function' ) {
            func();
        }
    },
	
    /**
     * Makes the HTMLElement with the specified ID invisible by slowly animating
     * the opacity property from its current value to 0.
     */
    fadeOut: function(id, func, endOpacity) {
        //speed = (speed == 'slow') ? 1500 : 500;
        var speed = 300;
        var end = endOpacity != null ? endOpacity : 0;
        opacity(id, 100, end, speed);
        
        if( func != null && typeof func == 'function' ) {
            func();
        }
    },
	
	trim: function(str, chars) {
		return this.ltrim( this.rtrim(str, chars), chars);
	},
 
	ltrim: function(str, chars) {
		chars = chars || "\\s";
		str = str || "";
		return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
	},
 
	rtrim: function(str, chars) {
		chars = chars || "\\s";
		str = str || "";
		return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
	},
	
    /**
     * Shows a HTML Dialog based on the params specified. If a callback func is specified,
     * it will be called once the dialog is made visible.
     */
    showDialog: function(params, func) {
        if( params == null ) {
            params = {};
        }
		
        pageManager.$('#pm-pane-content').innerHTML = pageManager._gd(params.content, '');
        pageManager.$('#pm-pane-header-title').innerHTML = pageManager._gd(params.title, 'Message');
        pageManager.$('#pm-ok-button').value = pageManager._gd(params.okButtonText, 'Done');
        pageManager.$('#pm-cancel-button').value = pageManager._gd(params.cancelButtonText, 'Cancel');
        pageManager.okButtonAction = pageManager._gd(params.okButtonAction, null);
        pageManager.cancelButtonAction = pageManager._gd(params.cancelButtonAction, null);
		
        if( pageManager._gd(params.cancelButtonVisible, true) ) {
            pageManager.$('#pm-cancel-button').style.display = "inline";
        } else {
            pageManager.$('#pm-cancel-button').style.display = "none";
        }
		
        // undocumented but useful properties
        pageManager.$('#pm-message-pane').style.width = pageManager._gd(params.width, 'auto');
        pageManager.$('#pm-pane-content').style.height = pageManager._gd(params.height, 'auto');
        pageManager.$('#pm-message-pane').style.top = pageManager._gd(params.top, '50%');
        pageManager.$('#pm-message-pane').style.left = pageManager._gd(params.left, '50%');
        pageManager.$('#pm-message-pane').style.position = pageManager._gd(params.position, 'fixed');
		
        if( pageManager._gd(params.autoCenter,true)  ) {
            pageManager.centerDialog();
        }
		
        // add a callback for the supplied function, and auto centering the dialog
        var func_call = function() {
            if( pageManager._gd(params.autoCenter,true) && !params.height  ) {
                pageManager.centerDialog();
            }
			
            if( func ) func();
        };
		
        if( params.showOverlay == null || params.showOverlay == true ) {
            pageManager.fadeIn('pm-overlay', function() {
                pageManager.show('pm-message-pane', func_call );
            }, 50);
        } else {
            pageManager.show('pm-message-pane', func_call );
        }
    },
	
    centerDialog: function() {
        changeOpac(0,'pm-message-pane');
        pageManager.$('#pm-message-pane').style.display = 'block';
        //pageManager.$('#pm-message-pane').style.height = 'auto';
		
        var w = pageManager.$('#pm-message-pane').offsetWidth;
        var h = pageManager.$('#pm-message-pane').offsetHeight;

        pageManager.$('#pm-message-pane').style.marginLeft = -(w/2) + "px";
        pageManager.$('#pm-message-pane').style.marginTop = -(h/2) + "px";
		
        if( pageManager.$('#pm-message-pane').offsetTop < 0 ) {
            pageManager.$('#pm-message-pane').style.top = "30px";
            pageManager.$('#pm-message-pane').style.marginTop = "0px";
        }
		
        pageManager.$('#pm-message-pane').style.display = 'none';
        changeOpac(100,'pm-message-pane');
    },

    /**
     * Hides the HTML Dialog and calls the specified callback function if one is
     * specified
     **/
    hideDialog: function(func) {
        pageManager.$('#pm-message-pane').style.display = 'none';
        pageManager.$('#pm-overlay').style.display = 'none';
		
        // if a callback is specfied, then call it once we close
        if( func ) {
            func();
        }
    },

    /**
     * Shows the HTML Dialog with message specified via the parameters object
     * passed
     */
    showMessage: function(params, func) {
        if( params == null ) {
            params = {
                okButtonText: "OK",
                cancelButtonVisible: false
            };
        } else {
            params.okButtonText = pageManager._gd(params.okButtonText , "OK");
            params.cancelButtonVisible = pageManager._gd(params.cancelButtonVisible, false);
        }
		
        pageManager.showDialog(params);
		
        // if a callback is specfied, then call it once we close
        if( func ) {
            func();
        }
    },

    /**
     * Shows an HTML Confirm Dialog based on the parameters specified
     **/
    showConfirmMessage: function(params) {
        if( params == null ) {
            params = {
                msgTitle: "Confirm Message",
                okButtonText: "OK"
            };
        } else {
            params.msgTitle = pageManager._gd(params.msgTitle, "Confirm Message");
            params.okButtonText = pageManager._gd( params.okButtonText, "OK");
        }
		
        pageManager.showDialog(params);
    },
    
    confirm: function(message, func) {
        this.showDialog({
            title: 'Confirm',
            content: message,
            okButtonText: "OK",
            okButtonAction: func
        });
    },
    
    inform: function(message) {
        this.showMessage({
            title: 'Message',
            content: message,
            cancelButtonVisible: false
        });
    },
	
    parseJSON: function(data) {
        var obj = null;
		
        if( JSON ) {
            try {
                obj = JSON.parse(data);
            } catch(e) {
                pageManager.showMessage({
                    title: 'Parse Error',
                    content: 'Failed To Parse JSON Data Returned From Server<br />Returned Data: ' + data
                });	
				
                return false;
            }
        }
		
        return obj;
    },

    /**
     * Private function that returns the value of the params object if present
     * or the default value instead.
     */
    _gd: function(param, defaultVal) {
        return param != null ? param : defaultVal;
    },

    /**
     * Creates a busy status object to use during AJAX calls
     */
    createBusyStatusIndicator: function() {
        
        var loaderContent = document.createElement("div");
        loaderContent.id = "loaderContent";

        var loaderImage = document.createElement("img");
        loaderImage.hspace = 5;
        loaderImage.id = "pm_loader_image";
        loaderImage.src = pageManager.loaderImageSrc;
        loaderImage.align = "absmiddle";
		
        var loaderMsg = document.createElement("span");
        loaderMsg.id = "pm_loader_msg";
        loaderMsg.innerHTML = "Loading Content. Please Wait...";

        loaderContent.appendChild( loaderImage );
        loaderContent.appendChild( loaderMsg );

        var loader = document.createElement("div");
        loader.style.display = "none";
        loader.id = "pm_loader";
        loader.appendChild(loaderContent);

        document.getElementsByTagName("body")[0].appendChild(loader);
		
        // add CSS Rule for loader content
        addCSSRule("#loaderContent", "margin-top: 20px; margin-bottom: 20px; font-size: 11px; font-weight: bold; text-align:center");
    },

    /**
     * Creates a hidden IFrame for AJAX GET and POST processing. An additional
     * hidden HTML Form is created to be used as a the base for AJAX POST requests
     * submitted to the IFrame.
     */
    createAJAXFrame: function() {
        var iframe = document.createElement("iframe");
        iframe.id = "pm_loader_frame";
        iframe.name = "pm_loader_frame";
        iframe.src = "about:blank";
		
        addCSSRule("#pm_loader_frame", "display:none; position: fixed; width: 300px; height: 300px; top: 0px; left: 0px;");

        document.getElementsByTagName("body")[0].appendChild(iframe);

        pageManager.addEvent("#pm_loader_frame",'load', pageManager.displayResult );
    },

    createMessagePane: function() {
        var paneHeader =  document.createElement('div');
        paneHeader.id = 'pm-pane-header';
        paneHeader.innerHTML = "<div id='pm-pane-header-title'>Message Header Will Go Here</div>" 
        + "<input id='pm-pane-header-x' value='X' type='button' />";

        var paneContent =  document.createElement('div');
        paneContent.id = 'pm-pane-content';
        paneContent.innerHTML = 'Message Will Go Here';

        var paneButtons = document.createElement('div');
        paneButtons.id = "pm-pane-button-pane";
        paneButtons.innerHTML = '<input type="button" id="pm-ok-button" value="OK"  />'
        + '<input type="button" id="pm-cancel-button" value="Cancel" />';
		

        var pane = document.createElement('div');
        pane.id = 'pm-message-pane';
        pane.style.display = "none";
		
        pane.appendChild(paneHeader);
        pane.appendChild(paneContent);
        pane.appendChild(paneButtons);
		
        var attr = "color: #000; background-color: #f1f1f1; border-bottom: solid #ccc 1px; font-family: Tahoma; font-size: 13px; font-weight: bold; padding: 6px; ";
        addCSSRule("#pm-pane-header", attr);
	
        addCSSRule("#pm-pane-content", "font-family: Tahoma, Geneva, sans-serif; font-size: 12px; padding: 10px; line-height: 18px; overflow: auto;");
		
        attr = "position: fixed; width: 35%; top: 200px; left: 32%; background-color: #fff; border: solid 1px #ccc; z-index: 1001; overflow: hidden; display: none; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px;";
        addCSSRule("#pm-message-pane", attr);
		
        addCSSRule("#pm-pane-button-pane", "padding: 5px; text-align: center; background-color: #efefef; border-top: solid #ccc 1px; bottom: 0px;");
		
        addCSSRule("#pm-ok-button, #pm-cancel-button","font-size: 13px; font-family: Tahoma; padding: 5px 12px; margin-left: 2px; margin-right: 2px;");
        
		
        document.getElementsByTagName("body")[0].appendChild(pane);

        // add the necessary events for the buttons
        pageManager.addEvent('pm-ok-button', 'click', function() {
            if( pageManager.okButtonAction != null && pageManager.okButtonAction() == false ) {
                return;
            }

            pageManager.hideDialog();

            // clear the action if it exists
            pageManager.okButtonAction = null;
        });

        pageManager.addEvent('pm-cancel-button', 'click', function() {
            if( pageManager.cancelButtonAction != null && pageManager.cancelButtonAction() == false ) {
                return;
            }
			
            pageManager.hideDialog();
			
            // clear the action if it exists
            pageManager.cancelButtonAction = null;
        });
		
        // register the event for the pm-pane-header-x button
        pageManager.addEvent('pm-pane-header-x','click', function() {
            pageManager.hideDialog();
        });
		
        // style pm-pane-header-x button
        attr = "position: absolute; right: 10px; top: 5px; font-family: Tahoma,Arial; font-size: 11px; font-weight: bold; padding-left: 4px; padding-right: 4px;";
        addCSSRule('#pm-pane-header-x', attr);
    },
	
    createOverlayPane: function() {
        
        var attr = "position: fixed; width: 100%; height: 100%; top: 0px; left: 0px; background-color: #000; opacity: 0.5;   display: none ";
        addCSSRule("#pm-overlay", attr);
        //overlayRule.style.filter = "alpha(opacity=50)";
		
        var overlay = document.createElement('div');
        overlay.style.display = "none";
        overlay.id = 'pm-overlay';
		
        document.getElementsByTagName("body")[0].appendChild(overlay);
    },

    /**
     * Initialises the PageManager object
     */
    init: function() {
        /*set user-agent flags*/
        var UA = navigator.userAgent.toLowerCase();
        var platform = navigator.platform.toLowerCase();
        var vendor = navigator.vendor || "";
		

        if (vendor === "KDE") {
            pageManager.isKonqueror = true;
            this.isSupported = false;
        } else if (typeof window.opera !== "undefined") {
            pageManager.isOpera = true;
            this.isSupported = true;
        } else if (UA.indexOf("msie") != -1) {
            pageManager.isIE = true;
            this.isSupported = true;
        } else if (vendor.indexOf("Apple") != -1) {
            pageManager.isSafari = true;
            this.isSupported = (platform.indexOf("mac") > -1);
        } else if (UA.indexOf("gecko") != -1) {
            pageManager.isGecko = true;
            this.isSupported = true;
        }
		

        pageManager.createAJAXFrame();
        pageManager.createBusyStatusIndicator();
        pageManager.createOverlayPane();
        pageManager.createMessagePane();
    }

};



/**
 * create a simple reference to the element function for simple chaining purposes
 * @return pageManager
 **/
function pm(selector) {
    return pageManager.el(selector);
}

function $p(selector) {
    return new pm(selector);
}

// make all pageManager functions accessible via the new $p alias
for(var key in pageManager) {
    $p[key] = pageManager[key];
}


/**
 * DomLoaded Object used to provide the ability for events to be fired
 * once the Document / DOM is loaded, instead of waiting until the entire
 * page loads, and Window.onload is called. Works for most major browsers
 * and older ones will fall back to the Window.onload call
 * 
 * For more info, see here: http://www.cherny.com/webdev/27/domloaded-updated-again
 */
var DomLoaded =
{
    onload: [],
    loaded: function()
    {
        if (arguments.callee.done) return;
        arguments.callee.done = true;
        for (i = 0;i < DomLoaded.onload.length;i++) DomLoaded.onload[i]();
    },
    load: function(fireThis)
    {
        this.onload.push(fireThis);
        if (document.addEventListener)
            document.addEventListener("DOMContentLoaded", DomLoaded.loaded, null);
        if (/KHTML|WebKit/i.test(navigator.userAgent))
        {
            var _timer = setInterval(function()
            {
                if (/loaded|complete/.test(document.readyState))
                {
                    clearInterval(_timer);
                    delete _timer;
                    DomLoaded.loaded();
                }
            }, 10);
        }
		
        /*@cc_on @*/
        /*@if (@_win32)
            var proto = "src='javascript:void(0)'";
            if (location.protocol == "https:") proto = "src=//0";
            document.write("<scr"+"ipt id=__ie_onload defer " + proto + "><\/scr"+"ipt>");
            var script = document.getElementById("__ie_onload");
            script.onreadystatechange = function() {
                if (this.readyState == "complete") {
                    DomLoaded.loaded();
                }
            };
        /*@end @*/
        window.onload = DomLoaded.loaded;
    }
};

// simple set of functions for changing this opacity of objects
// this has not been added to current pageManager object since the scoping tends to be
// problematic. This will however, be resolved later for a better object oriented approach
// to including this functionality
function opacity(id, opacStart, opacEnd, millisec) {
    //speed for each frame
    var speed = Math.round(millisec / 100);
    var timer = 0;

    //determine the direction for the blending, if start and end are the same nothing happens
    if(opacStart > opacEnd) {
        for(i = opacStart; i >= opacEnd; i--) {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    } else if(opacStart < opacEnd) {
        for(i = opacStart; i <= opacEnd; i++)
        {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    }
}

//change the opacity for different browsers
function changeOpac(opacity, id) {
    var object = document.getElementById(id).style;
    object.display = "block";
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
}

function shiftOpacity(id, millisec) {
    //if an element is invisible, make it visible, else make it ivisible
    if(document.getElementById(id).style.opacity == 0) {
        opacity(id, 0, 100, millisec);
    } else {
        opacity(id, 100, 0, millisec);
    }
}

function getCSSRule(ruleName, deleteFlag) {               // Return requested style obejct
    ruleName=ruleName.toLowerCase();                       // Convert test string to lower case.
    if (document.styleSheets) {                            // If browser can play with stylesheets
        for (var i=0; i<document.styleSheets.length; i++) { // For each stylesheet
            var styleSheet=document.styleSheets[i];          // Get the current Stylesheet
            var ii=0;                                        // Initialize subCounter.
            var cssRule=false;                               // Initialize cssRule.
            do {                                             // For each rule in stylesheet
                if (styleSheet.cssRules) {                    // Browser uses cssRules?
                    cssRule = styleSheet.cssRules[ii];         // Yes --Mozilla Style
                } else {                                      // Browser usses rules?
                    cssRule = styleSheet.rules[ii];            // Yes IE style.
                }                                             // End IE check.
                if (cssRule)  {                               // If we found a rule...
                    if (cssRule.selectorText && cssRule.selectorText.toLowerCase() == ruleName) { //  match ruleName?
                        if (deleteFlag=='delete') {             // Yes.  Are we deleteing?
                            if (styleSheet.cssRules) {           // Yes, deleting...
                                styleSheet.deleteRule(ii);        // Delete rule, Moz Style
                            } else {                             // Still deleting.
                                styleSheet.removeRule(ii);        // Delete rule IE style.
                            }                                    // End IE check.
                            return true;                         // return true, class deleted.
                        } else {                                // found and not deleting.
                            return cssRule;                      // return the style object.
                        }                                       // End delete Check
                    }                                          // End found rule name
                }                                             // end found cssRule
                ii++;                                         // Increment sub-counter
            } while (cssRule);                               // end While loop
        }                                                   // end For loop
    }                                                      // end styleSheet ability check
    return false;                                          // we found NOTHING!
}                                                         // end getCSSRule 

function deleteCSSRule(ruleName) {                          // Delete a CSS rule   
    return getCSSRule(ruleName,'delete');                  // just call getCSSRule w/delete flag.
}                                                         // end killCSSRule

function addCSSRule(ruleName, ruleAttributes) {                         // Create a new css rule
    if( ruleAttributes == null ) ruleAttributes = "";
	
    if (document.styleSheets) {                            // Can browser do styleSheets?
   		
        // if no stylesheet exists, then create one
        if( document.styleSheets.length == 0 ) {
            var cssNode = document.createElement('style');
            cssNode.type = 'text/css';
            cssNode.rel = 'stylesheet';
            cssNode.media = 'screen';
            cssNode.title = 'dynamicSheet';
            document.getElementsByTagName("head")[0].appendChild(cssNode);
        }
	  
        if (!getCSSRule(ruleName)) {                        // if rule doesn't exist...
            if (document.styleSheets[0].addRule) {           // Browser is IE?
                document.styleSheets[0].addRule(ruleName, ruleAttributes,0);      // Yes, add IE style
            } else {                                         // Browser is IE?
                try {
                    var sheet = document.styleSheets[0];
                    sheet.insertRule(ruleName + ' {' + ruleAttributes + ' }', sheet.cssRules.length - 1); // Yes, add Moz style.
                } catch(e) {}
            }                                                // End browser check
        }                                                   // End already exist check.
    }                                                      // End browser ability check.
    return getCSSRule(ruleName);                           // return rule we just created.
} 

pageManager.setLoaderImageSrc("../assets/images/general/loadcircles.gif");
pageManager.addLoadEvent( pageManager.init );